package erfgame.core.memory;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.logging.Logger;

public abstract class MemoryPool<Type> {
	
	private Logger log = Logger.getLogger(MemoryPool.class.getName());
	
	private ArrayList<WeakReference<InMemoryObject<Type>>> freeMemory;

	
	public MemoryPool()
	{
		this.freeMemory = new ArrayList<WeakReference<InMemoryObject<Type>>>();
	}
	
	public void add( InMemoryObject<Type> value )
	{
		this.freeMemory.add( new WeakReference<InMemoryObject<Type>>(value) );
	}
	
	public InMemoryObject<Type> claim(boolean clean)
	{
		// do we have a free one?
		for( int i=freeMemory.size(); i>0; ) {
			i--;
			WeakReference<InMemoryObject<Type>> ref = freeMemory.remove(i);
			InMemoryObject<Type> o = ref.get();
			if( o != null ) {
//				log.info("claimed existing memory");
				if( clean ) {
					clean( o.getValue() );
				}
				return o;
			}
		}
		// we don't have any free, create one
//		log.info("claimed new memory");
		Type value = create();
		return new InMemoryObject<Type>(this, value);
	}
	
	protected abstract void clean(Type object);
	
	protected abstract Type create();
}
